package com.itjcloud.iot.gateway.filter.global;

import com.itjcloud.iot.gateway.client.IotClient;
import com.itjcloud.iot.gateway.model.CheckSignResultDTO;
import com.itjcloud.iot.gateway.model.CommonTokenInfo;
import com.itjcloud.iot.gateway.model.IotSignatureBO;
import com.itjcloud.iot.gateway.model.ServiceRequestException;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Component
@RequiredArgsConstructor
@Order(2)
@Slf4j
public class VerifySignatureFilter implements GlobalFilter {
    private final IotClient iotClient;


    @Override
    @NonNull
    public Mono<Void> filter(@NonNull ServerWebExchange exchange, @NonNull GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        return IotSignatureBO.init(request)
                .flatMap(item -> {
                    String deviceId = item.getDeviceId();
                    String signature = item.getSignature();
                    Mono<DataBuffer> dataBuffer1 = item.createDataBuffer();
                    Flux<DataBuffer> body = exchange.getRequest().getBody();
                    Flux<DataBuffer> concat = Flux.concat(dataBuffer1, body);
                    return iotClient.postResource(deviceId, signature, concat)
                            .flatMap(ite -> {
                                log.info("打印请求iot的响应信息{}", ite);
                                if (ite.isOk()) {
                                    CheckSignResultDTO data = ite.getData();
                                    CommonTokenInfo commonTokenInfo = new CommonTokenInfo();
                                    commonTokenInfo.setChildOrgId(data.getChildOrgId());
                                    commonTokenInfo.setOrgId(data.getOrgId());
                                    commonTokenInfo.setTenantId(data.getOrgId());
                                    commonTokenInfo.setAuthenticated(true);
                                    return Mono.just(commonTokenInfo);
                                }
                                return Mono.error(new ServiceRequestException(ite, "签名验证失败"));

                            })
                            .doOnNext(ite -> exchange.getAttributes().put(CommonTokenInfo.class.getName(), ite))
                            .flatMap(ite -> chain.filter(exchange));
                })
                .switchIfEmpty(chain.filter(exchange));
    }


}

